#ifndef __TINY_TEST__

#include "vbb_CARD.h"
#include "fw/vbb_RTC.h"
#include "ff.h"
#include <string.h>
#include "vbb_Header.h"
#include "vbb_flashmem.h"
#include "mmc.h"

extern VBB_FlashMem flashMem;

FATFS _fatfs[1];

VBB_Card card;

void SD_Select(void)
{    
    if (vbb_DeviceModel() == CNS03)
        (GPIOC->BSRR |= (1 << (4 + 16)));    
    else if (vbb_DeviceModel() == CNS01)
        (GPIOB->BSRR |= (1 << (7 + 16)));
}

void SD_Deselect(void)
{    
    if (vbb_DeviceModel() == CNS03)
        (GPIOC->BSRR |= (1 << 4));    
    else if (vbb_DeviceModel() == CNS01)
        (GPIOB->BSRR |= (1 << 7));
}

char SD_Put(char Data)
{
    return vbb_SPI_WriteByte(&(card.spi), Data);
}

void vbb_CARD_Init()
{    
    int i = 0;
    int r = 0;
    unsigned int start_clock;    
    
    vbb_OUTPUT_Print("INFO: Initializing SD Card access ");

    if (vbb_DeviceModel() == CNS03)
    {
        vbb_PIN_Init(&(card.selectPin), GPIOC, 4, PIN_MODE_GENERAL_OUTPUT_PUSH_PULL);
        vbb_SPI_Init(&(card.spi), SPI1);
    }
    else if (vbb_DeviceModel() == CNS01)
    {
        vbb_PIN_Init(&(card.selectPin), GPIOB, 7, PIN_MODE_GENERAL_OUTPUT_PUSH_PULL);
        card.spi = flashMem.flash.spi;        
    }
    else if (vbb_DeviceModel() == BA01)
    {
        /*vbb_PIN_Init(&(card.selectPin), GPIOB, 7, PIN_MODE_GENERAL_OUTPUT_PUSH_PULL);
        card.spi = flashMem.flash.spi;*/
        vbb_OUTPUT_Print("[DISABLE]\r\n");
        return;
    }
    
    SD_Select();
    vbb_DelayMillis(100);
    SD_Deselect();
    vbb_DelayMillis(100);
    
    SD_Select();
    vbb_DelayMillis(100);
    for (i = 0; i < 80; i++)
        vbb_SPI_WriteByte(&(card.spi), 255);
    vbb_DelayMillis(100);
    SD_Deselect();
    
    SD_Select();
    vbb_DelayMillis(100);
    vbb_SPI_WriteByte(&(card.spi), 0x40);
    vbb_SPI_WriteByte(&(card.spi), 0 >> 24);
    vbb_SPI_WriteByte(&(card.spi), 0 >> 16);
    vbb_SPI_WriteByte(&(card.spi), 0 >> 8);
    vbb_SPI_WriteByte(&(card.spi), 0);
    vbb_SPI_WriteByte(&(card.spi), 0x95);
    
    start_clock = vbb_RTC_GetSec();
    while (r != 0x01)
    {
        if (vbb_RTC_GetSec() - start_clock > 2)        
            break;
        r = vbb_SPI_WriteByte(&(card.spi), 255);
    }
    SD_Deselect(); 

    if (r == 0x01)
    {
        vbb_OUTPUT_Print( "[SUCCESS]\r\n");
        f_mount(0, &_fatfs[0]);
    }
    else
        vbb_OUTPUT_Print("[FAIL]\r\n");
}

FIL  _file;

void vbb_CARD_PushMessage(const char * FileName, const char * Message)
{
    bool rt = FALSE;
    unsigned int bw;    
        
    vbb_OUTPUT_Print("DEBUG: Write message into SD Card (");
    
    vbb_OUTPUT_PrintDebug(FileName);
    vbb_OUTPUT_Print(")");    
    
    if (vbb_DeviceModel() == BA01)
    {
        vbb_OUTPUT_Print("[FAIL]\r\n");
        vbb_OUTPUT_PrintDebug(Message);
        vbb_OUTPUT_Print("\r\n");
    }
    else
    {    
        rt = f_open(&_file, FileName, FA_OPEN_ALWAYS | FA_WRITE);
        if (rt == FR_OK)
        {
            f_lseek(&_file, _file.fsize);
            f_write(&_file, Message, strlen(Message), &bw);
            f_close(&_file);
            
            vbb_OUTPUT_Print("[SUCCESS]\r\n");
            vbb_OUTPUT_PrintDebug(Message);
            vbb_OUTPUT_Print("\r\n");
        }
        else
        {
            vbb_OUTPUT_Print("[FAIL]\r\n");
            vbb_OUTPUT_PrintDebug(Message);
            vbb_OUTPUT_Print("\r\n");
        }
    }
}

#endif
